/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.test_finder;

import picounit.Ignore;
import picounit.IgnoreReason;
import picounit.features.test_instantiator.ImplementsCondition;
import picounit.features.test_instantiator.TestInstantiator;
import picounit.util.Equal;
import picounit.verify.constraint.EqualUtil;
import junit.framework.TestSuite;

class IgnoreCondition implements Equal<IgnoreCondition> {
	private final ImplementsCondition implementsCondition;
	private final TestInstantiator testInstantiator;

	public IgnoreCondition(TestInstantiator testInstantiator) {
		this.implementsCondition = new ImplementsCondition(Ignore.class);
		this.testInstantiator = testInstantiator;
	}
	
	@SuppressWarnings("unchecked")
	public boolean addToSuiteIfIgnored(Class<?> aClass, TestSuite ignoredTestSuite) {
		if (!implementsCondition.matches(aClass)) {
			return false;
		}

		IgnoreReason ignoreReason = getReason(aClass);

		if (ignoreReason.isIgnored()) {
			ignoredTestSuite.addTest(
				new IgnoredTestSuite(aClass, ignoreReason.ignoreWhy()));

			return true;
		}

		return false;
	}
	
	public boolean usesTestInstantiator(TestInstantiator testInstantiator) {
		return this.testInstantiator.equals(testInstantiator);
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Equal methods
	///////////////////////////////////////////////////////////////////////////////////////////////
	
	public boolean equalTo(IgnoreCondition other) {
		return other.usesTestInstantiator(testInstantiator);
	}
	
	///////////////////////////////////////////////////////////////////////////////////////////////
	// Object Methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	@Override
	public boolean equals(Object object) {
		return EqualUtil.isEqual(this, object);
	}
	
	@Override
	public int hashCode() {
		return getClass().hashCode();
	}

	@Override
	public String toString() {
		return "Ignore[" + implementsCondition + "," + testInstantiator + "]";
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Implementation
	///////////////////////////////////////////////////////////////////////////////////////////////

	@SuppressWarnings("unchecked")
	private IgnoreReason getReason(Class aClass) {
		IgnoreReason ignoreReason = new IgnoreReason();

		try {
			Ignore ignore = (Ignore) testInstantiator.instantiate(aClass);

			ignore.ignoredWhen(ignoreReason);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return ignoreReason;
	}
}
